package com.engine.ld.optimize;


import com.wbi.action.ECException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import weaver.conn.RecordSet;
import weaver.general.BaseBean;
import weaver.general.Util;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.StringReader;

/**
 * @Auther: DengJP
 * @Date: 2021/6/18 10:17
 * @Description: 采购申请接口xml数据封装与返回结果解析
 */
public class PurchasingRequisitionParseXmlUtil {

    private static final BaseBean bb = new BaseBean();

    /**
     * 通过requestid获取OA流程数据，封装为SAP要求的xml数据
     * @param requestid 流程的requestid
     * @return 解析之后的xml字符串
     */
    public String parseImportXml(String requestid) throws ParserConfigurationException {
        // 获取流程数据
        String sql = "select dt.BSART, dt.BANFN, dt.BNFPO, dt.KNTTP, dt.EPSTP, dt.MATNR, dt.TXZ01, dt.MENGE, dt.BAMEI, dt.LFDAT, dt.MATKL, dt.WERKS, dt.LGORT, dt.EKGRP, dt.AFNAM, dt.BEDNR, dt.KOSTL, dt.ANLN1, dt.EBKNMENGE, dt.AUFNR, dt.ZFLAG, dt.ELOEK, dt.LIFNR, dt.FLIEF, dt.INFNR, dt.EKORG \n" +
                "from formtable_main_120 a\n" +
                "left join formtable_main_120_dt1 dt on a.id = dt.mainid\n" +
                "where a.requestid = ?";
        RecordSet rs = new RecordSet();
        rs.executeQuery(sql, requestid);
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document document = builder.newDocument();
        Element root = document.createElement("ROOT");
        document.appendChild(root);
        if(rs.next()) {
            appendChild(document, root, "BANFN", Util.null2String(rs.getString("BANFN")));  // 采购申请编号
            appendChild(document, root, "BNFPO", Util.null2String(rs.getString("BNFPO")));  // 采购申请的项目编号
//            appendChild(document, root, "KNTTP", Util.null2String(rs.getString("KNTTP")));  // 科目分配类别
            appendChild(document, root, "EPSTP", Util.null2String(rs.getString("EPSTP")));  // 采购凭证中的项目类别
            appendChild(document, root, "MATNR", Util.null2String(rs.getString("MATNR")));  // 物料
            appendChild(document, root, "TXZ01", Util.null2String(rs.getString("TXZ01")));  // 短文本
            appendChild(document, root, "MENGE", Util.null2String(rs.getString("MENGE")));  // 申请数量
            appendChild(document, root, "BAMEI", Util.null2String(rs.getString("BAMEI")));  // 采购申请计量单位
            appendChild(document, root, "LFDAT", Util.null2String(rs.getString("LFDAT"))); // 交货日期
            appendChild(document, root, "MATKL", Util.null2String(rs.getString("MATKL")));  // 物料组
            appendChild(document, root, "WERKS", Util.null2String(rs.getString("WERKS")));  // 工厂
            appendChild(document, root, "LGORT", Util.null2String(rs.getString("LGORT")));  // 库存地点
            appendChild(document, root, "EKGRP", Util.null2String(rs.getString("EKGRP")));  // 采购组
            appendChild(document, root, "AFNAM", Util.null2String(rs.getString("AFNAM")));  // 申请者
            appendChild(document, root, "BEDNR", Util.null2String(rs.getString("BEDNR")));  // 跟踪号
            appendChild(document, root, "KOSTL", Util.null2String(rs.getString("KOSTL")));  // 成本中心
            appendChild(document, root, "ANLN1", Util.null2String(rs.getString("ANLN1")));  // 资产卡片号
            appendChild(document, root, "ZMENGE", Util.null2String(rs.getString("EBKNMENGE")));  // 资产数量
            appendChild(document, root, "AUFNR", Util.null2String(rs.getString("AUFNR"))); // 订单
            appendChild(document, root, "ZFLAG", Util.null2String(rs.getString("ZFLAG")));  // 业务标识
            appendChild(document, root, "ELOEK", Util.null2String(rs.getString("ELOEK")));  // 采购申请删除标识
            appendChild(document, root, "FRGGR", "");
            appendChild(document, root, "FRGKZ", "");
            appendChild(document, root, "FRGZU", "");
            appendChild(document, root, "FRGST", "");
            appendChild(document, root, "LIFNR", Util.null2String(rs.getString("LIFNR")));  //  期望的供应商
            appendChild(document, root, "FLIEF", Util.null2String(rs.getString("FLIEF")));  // 固定的供应商
            appendChild(document, root, "INFNR", Util.null2String(rs.getString("INFNR")));  // 信息记录
            appendChild(document, root, "EKORG", Util.null2String(rs.getString("EKORG")));  // 采购组织
            appendChild(document, root, "BSART", Util.null2String(rs.getString("BSART"))); // 采购申请凭证类型
        }
        bb.writeLog("result: " + createXmlToString(document));
        return createXmlToString(document);
    }

    /**
     * 将xml返回的数据，解析之后保存到表单中
     * @param requestid 流程的requestid
     * @param xmlResult SAP返回结果的Xml字符串
     */
    public static void fetchResultUpdateWorkflow(String requestid, String xmlResult) {
        bb.writeLog("请求返回的xmlResult：" + xmlResult);
        String updateSql = "update formtable_main_120 set TYPE = ?, MESSAGE = ? where requestid = ?";
        if(xmlResult == null || "".equals(xmlResult) || requestid == null || "".equals(requestid)) {
            throw new ECException("参数不全");
        }

        xmlResult = trimXmlStr(xmlResult);
        Document document;
        try {
            document = strToDocument(xmlResult);
        } catch(Exception e) {
            bb.writeLog("XML解析失败: " + e.getMessage());
            bb.writeLog("xmlResult: " + xmlResult);
            throw new ECException("XML解析失败: " + e.getMessage());
        }

        Element root = document.getDocumentElement();
        NodeList typeNodeList = root.getElementsByTagName("TYPE");
        NodeList messageNodeList = root.getElementsByTagName("MESSAGE");

        if(typeNodeList.getLength() > 0 && messageNodeList.getLength() > 0) {
            String type = Util.null2String(typeNodeList.item(0).getTextContent());
            String message = Util.null2String(messageNodeList.item(0).getTextContent());
            bb.writeLog("type: " + type);
            bb.writeLog("message : " + message);
            RecordSet rs = new RecordSet();
            rs.executeUpdate(updateSql, type, message, requestid);
        } else {
            bb.writeLog("未获取到正常返回数据");
            bb.writeLog("xmlResult: " + xmlResult);
            throw new ECException("未获取到正常返回数据");
        }

    }

    /**
     * 去除<_--5CTYPE_--3DSTRING>之前部分，去除</_--5CTYPE_--3DSTRING>之后部分
     * @param xmlString xml字符串
     * @return 去除头尾部分的xml字符串
     */
    private static String trimXmlStr(String xmlString) {
        if(!xmlString.contains("<_--5CTYPE_--3DSTRING>")) {
            return xmlString;
        }
        int start = xmlString.indexOf("<_--5CTYPE_--3DSTRING>") + "<_--5CTYPE_--3DSTRING>".length();
        int end = xmlString.indexOf("</_--5CTYPE_--3DSTRING>");
        return xmlString.substring(start, end).trim();
    }

    /**
     * 生成xml字符串
     * @param document Document树对象
     * @return 整个xml字符串
     */
    private static String createXmlToString(Document document){
        String xmlString = null;
        try {
            // 创建TransformerFactory工厂对象
            TransformerFactory transFactory = TransformerFactory.newInstance();
            // 通过工厂对象, 创建Transformer对象
            Transformer transformer = transFactory.newTransformer();
            transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
            //使Xml自动换行, 并自动缩进
            transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, "");
            transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");  //中间的参数网址固定写法(这里还没搞懂)
            transformer.setOutputProperty(OutputKeys.INDENT, "yes");                          //是否设置缩进（indent: yes|no）
            // 创建DOMSource对象并将Document加载到其中
            DOMSource domSource = new DOMSource(document);
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            // 使用Transformer的transform()方法将DOM树转换成XML
            transformer.transform(domSource, new StreamResult(bos));
            xmlString = bos.toString();
        } catch (TransformerException e) {
            e.printStackTrace();
        }
        return xmlString;
    }

    /**
     * 将字符串转为xmldom对象
     * @param xmlString xml字符串
     * @return dom对象
     * @throws ParserConfigurationException 创建document对象异常
     * @throws IOException IO异常
     * @throws SAXException 解析异常
     */
    private static Document strToDocument(String xmlString) throws ParserConfigurationException, IOException, SAXException {

        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        dbf.setNamespaceAware(true);
        DocumentBuilder documentBuilder = dbf.newDocumentBuilder();
        return documentBuilder.parse(
                new InputSource(new StringReader(xmlString)));
    }




    /**
     * document对象中添加子项
     * @param document ducument对象
     * @param parent 父元素
     * @param key 元素标签
     * @param value 元素content值
     */
    private static void appendChild(Document document, Element parent, String key, String value) {
        Element child = document.createElement(key);
        if(child != null) {
            child.setTextContent(value);
        }
        parent.appendChild(child);
    }

}
